package com.yyge.common.util;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.yyge.common.constans.RedisConstans;
import com.yyge.common.constans.WaimaiConst;

import com.yyge.controller.admin.login.resp.AdminLoginResp;
import com.yyge.controller.mobile.login.resp.MobileLoginResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 作令牌服务(创建令牌，验证令牌，刷新令牌，删除令牌)
 * @author Administrator
 */
@Component
public class TokenUtil {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 生成令牌
     * @param loginVO
     * @return
     */
    public String createJwtToken(AdminLoginResp loginVO){
        loginVO.setToken(IdUtil.fastUUID().toString());
        DateTime expiredDate = DateUtil.offsetMinute(new Date(), RedisConstans.TOKEN_EXPIRED_MINTUES);
        loginVO.setExpiredTime(expiredDate);

        //存储到redis中
        refreshToken(loginVO);

        //把uuid加密成 jwt值  https://doc.hutool.cn/pages/JWTUtil/#%E4%BD%BF%E7%94%A8
        Map<String, Object> map = new HashMap<String, Object>() {
            private static final long serialVersionUID = 1L;
            {    put( WaimaiConst.TOKEN,  loginVO.getToken() );
            }
        };

        String jwtToken=JWTUtil.createToken(map, WaimaiConst.JWT_SECURITY.getBytes());
        return jwtToken;
    }

    /**
     * 更新redis中的令牌的值
     * @param loginVO
     */
    public void refreshToken(AdminLoginResp loginVO){
        //大
       Date expiredTime=loginVO.getExpiredTime();
       //小
       Date now=new Date();
       // 过期时间-当前时间<=10分钟  ，续时
       if(expiredTime.getTime() - now.getTime()<= WaimaiConst.TEN_MINTUES){
           DateTime expiredDate = DateUtil.offsetMinute(new Date(), RedisConstans.TOKEN_EXPIRED_MINTUES);
          loginVO.setExpiredTime(expiredDate);
       }

       //更新redis  login:uuid
        String redisKey= RedisConstans.getRedisKey(RedisConstans.TOKEN_KEY, loginVO.getToken());
       this.redisTemplate.opsForValue().set(redisKey, loginVO,RedisConstans.TOKEN_EXPIRED_MINTUES, TimeUnit.MINUTES);
    }

    /**
     * 把jwt字符解密还原成uuid
     * @param jwtToken
     * @return
     */
    public String jwtDecodeToUUID(String jwtToken){

        JWT jwt = JWTUtil.parseToken(jwtToken);
        String uuid=jwt.getPayload(WaimaiConst.TOKEN).toString();
        return uuid;
    }

    /**
     * 根据uuid查询redis中的值
     * @param uuid
     * @return
     */
    public AdminLoginResp getRedisLoginVO(String uuid){
        if(StrUtil.isBlank(uuid)){
            return null;
        }
        String redisKey=RedisConstans.getRedisKey(RedisConstans.TOKEN_KEY,uuid);
        Object redisObject=this.redisTemplate.opsForValue().get(redisKey);
        if(redisObject==null){
            return null;
        }
        return (AdminLoginResp) redisObject;
    }

    /**
     * 根据令牌删除 redis中的值
     * @param uuid
     */
    public void removeRedisLoginVO(String uuid){
        if(StrUtil.isNotBlank(uuid)){
            String redisKey=RedisConstans.getRedisKey(RedisConstans.TOKEN_KEY,uuid);
            this.redisTemplate.delete(redisKey);
        }
    }

    /**
     * 手机端生成令牌
     * @param resp 用户对象
     * @return 字符串
     */
    public String createMobileJwtToken(MobileLoginResp resp){
        resp.setToken(IdUtil.fastUUID().toString());
        DateTime expiredDate = DateUtil.offsetMinute(new Date(),RedisConstans.MOBILE_TOKEN_EXPIRED_MINTUES);
        resp.setExpiredTime(expiredDate);

        //存储到Redis中
        refreshMobileToken(resp);

        //把uuid加密生产jwt值
        Map<String,Object> map=new HashMap<String,Object>(){
            private static  final long serialVersionUID=1L;
            {put(WaimaiConst.TOKEN,resp.getToken());}
        };

        String jwtToken=JWTUtil.createToken(map,WaimaiConst.JWT_SECURITY.getBytes());
        return jwtToken;
    }

    /**
     * 更新redis手机端令牌的值
     * @param resp
     */
    public void refreshMobileToken(MobileLoginResp resp){
        //大
        Date expiredTime=resp.getExpiredTime();

        //小
        Date now=new Date();

        //过期时间-当前时间<=10分钟,那么就续时间
        if(expiredTime.getTime() - now.getTime() <= WaimaiConst.TEN_MINTUES){
            DateTime expiredDate=DateUtil.offsetMinute(new Date(),RedisConstans.MOBILE_TOKEN_EXPIRED_MINTUES);
            resp.setExpiredTime(expiredDate);
        }

        //更新redis
        String redisKey=RedisConstans.getRedisKey(RedisConstans.MOBILE_TOKEN_KEY,resp.getToken());
        redisTemplate.opsForValue().set(redisKey,resp,RedisConstans.MOBILE_TOKEN_EXPIRED_MINTUES,TimeUnit.MINUTES);
    }

    /**
     * 根据令牌删除redis中的值
     * @param uuid 字符串uuid
     */

    public void removeMobileRedisLoginVO(String uuid){
        if(StrUtil.isNotBlank(uuid)){
            String redisKey=RedisConstans.getRedisKey(RedisConstans.MOBILE_TOKEN_KEY,uuid);
            redisTemplate.delete(redisKey);
        }
    }


    /**
     * 根据uuid查询redis中的值
     * @param uuid
     * @return
     */
    public MobileLoginResp getRedisMobileLoginVO(String uuid){
        if(StrUtil.isBlank(uuid)){
            return null;
        }
        String redisKey=RedisConstans.getRedisKey(RedisConstans.MOBILE_TOKEN_KEY,uuid);
        Object redisObject=this.redisTemplate.opsForValue().get(redisKey);
        if(redisObject == null){
            return null;
        }
        return (MobileLoginResp) redisObject;
    }
}
